#include<cppr.hpp>
using namespace std;
/*
虚函数用来实现多态，是建立在方法覆盖的基础上的，也就是父类中必须有虚函数。
在方法覆盖的时候，如果把父类的函数前面加上virtual关键字，那么父类和子类的同名同参（方法覆盖）函数全都成为虚函数。
系统会把父类和子类中所有的虚函数列一个表，当通过父类指针调用某个虚函数的时候，系统会先检测父类的指针指向的是哪个对象，再从虚函数表中找到该对象的虚函数来进行调用，这种调用方式也叫做动态联编。
静态联编：就是函数重载
动态联编：通过多态来实现
*/
class Animal // 如果不加virtual，则调用的是父类的函数
{
public:
    virtual void speak() // 虚函数
    {
        cout << "animal speak" << endl;
    }
    virtual void run() // 虚函数
    {
        cout << "animal run" << endl;
    }
    virtual void eat() // 虚函数
    {
        cout << "animal eat" << endl;
    }
    virtual void sleep() // 虚函数
    {
        cout << "animal sleep" << endl;
    }
};
class Dog : public Animal
{
public:
    void speak()
    {
        cout << "dog speak" << endl;
    }
    void run()
    {
        cout << "dog run" << endl;
    }
    void eat()
    {
        cout << "dog eat" << endl;
    }
    void sleep()
    {
        cout << "dog sleep" << endl;
    }
};
class Cat : public Animal
{
public:
    void speak()
    {
        cout << "cat speak" << endl;
    }
    void run()
    {
        cout << "cat run" << endl;
    }
    void eat()
    {
        cout << "cat eat" << endl;
    }
    void sleep()
    {
        cout << "cat sleep" << endl;
    }
};

int main()
{
    Animal *animal; // 父类指针
    cout << "请输入要创建的动物类型:1.狗 2.猫" << endl;
   int a = 0;
    cin >> a;
    if (a == 1)
    {
        animal = new Dog; // 父类指针指向子类对象,实现多态.如果不加virtual，则调用的是父类的函数
    }
    else if (a == 2)
    {
        animal = new Cat;
    }
    animal->speak();
    animal->run();
    animal->eat();
    animal->sleep();
    delete animal;
    return 0;
}